AmazonS3AsyncClientは存在しない 〜 TransferManagerの紹介
よく訓練されたアップル信者、都元です。自分、まいどまいどヘヴィーなエントリばっかり書いてしまう癖があるので、たまにはライトな奴を投下しようと思います。
AWS SDK for Javaには、通常のAPIラッパー(例えば、AmazonEC2Client/AmazonEC2)と、非同期処理対応のラッパー(例えば、AmazonEC2AsyncClient/AmazonEC2Async)がセットで用意されている事が多いです。通常処理はResponseを返すのに対し、非同期APIではFuture<Response>を返すような仕組みになっています。
ところで、AmazonS3については、AmazonS3AsyncClient/AmazonS3Asyncというクラスが提供されていません。本エントリは、「無い!!何で!?」と思って「AmazonS3AsyncClient」というキーワードでググった人に見つけてもらえればなぁ、と願ってをります。
S3の非同期処理
とは言え、S3の非同期処理はサポートされていないわけではなく、なぜかTransferManagerという名前で提供されています。しかも、単にFutureで対応するようなプリミティブなものではなく、もっと高水準の処理(ステータスのチェック、転送完了イベントのハンドリング、転送のキャンセル等)が用意されているのが嬉しいところです。だから命名パターンから外れたのでしょうかね。
例えば、ファイルのアップロードはこんな感じ。uploadメソッドは非同期で実行され、アップロードが完了しなくても処理が帰ってきます。その後、アップロードが完了するまで標準出力に進捗を表示し続けます。
TransferManager transferManager = new TransferManager(credentials); Upload upload = transferManager.upload(bucketName, file.getName(), file); while (upload.isDone() == false) { System.out.println(upload.getProgress().getPercentTransfered() + "%"); }
また、リスナを仕掛けて同様の機能を実現することもできます。
TransferManager transferManager = new TransferManager(credentials); final Upload upload = transferManager.upload(bucketName, file.getName(), file); upload.setProgressListener(new ProgressListener() { @Override public void progressChanged(ProgressEvent progressEvent) { System.out.println(upload.getProgress().getPercentTransfered() + "%"); if (progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) { System.out.println("Upload complete!!!"); } } }; upload.waitForCompletion();
その他、TransferManagerはアップロード時にそのファイルサイズ等を考慮し、可能であればファイルを複数のパートに分割し、並列アップロードによってパフォーマンスを上げる、といったことまでサポートしてくれます。この方式だと、万が一通信エラーが発生した場合でも全体を再転送する必要はなく、再試行すべきなのは1つのパートだけ、という利点もあります。
小ネタでした。